<?php
session_start();
require_once '../config.php';

// 检查是否登录
if (!isset($_SESSION['admin_id'])) {
    header('Content-Type: application/json');
    echo json_encode(['success' => false, 'message' => '未授权访问']);
    exit;
}

// 获取管理员信息
$stmt = $pdo->prepare("SELECT * FROM admins WHERE id = ?");
$stmt->execute([$_SESSION['admin_id']]);
$admin = $stmt->fetch();

// 检查是否是POST请求
if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
    header('Content-Type: application/json');
    echo json_encode(['success' => false, 'message' => '请求方法不正确']);
    exit;
}

// 检查操作类型
$action = $_POST['action'] ?? '';
if ($action !== 'update') {
    header('Content-Type: application/json');
    echo json_encode(['success' => false, 'message' => '操作类型不正确']);
    exit;
}

// 获取版本和下载链接
$version = $_POST['version'] ?? '';
$download_url = $_POST['download_url'] ?? '';
$do_backup = isset($_POST['backup']) ? (bool)$_POST['backup'] : false;

if (empty($version) || empty($download_url)) {
    header('Content-Type: application/json');
    echo json_encode(['success' => false, 'message' => '参数不完整']);
    exit;
}

// 设置超时时间
set_time_limit(300); // 5分钟

// 创建临时目录
$temp_dir = '../temp';
if (!is_dir($temp_dir)) {
    if (!mkdir($temp_dir, 0755, true)) {
        header('Content-Type: application/json');
        echo json_encode(['success' => false, 'message' => '无法创建临时目录']);
        exit;
    }
}

// 清理临时目录
array_map('unlink', glob("$temp_dir/*.*"));

// 下载更新包
$update_file = "$temp_dir/update.zip";
$download_success = false;

try {
    // 使用file_get_contents下载
    $file_content = @file_get_contents($download_url);
    if ($file_content !== false) {
        if (file_put_contents($update_file, $file_content)) {
            $download_success = true;
        }
    }
    
    // 如果上面的方法失败，尝试使用curl下载
    if (!$download_success && function_exists('curl_init')) {
        $ch = curl_init($download_url);
        $fp = fopen($update_file, 'w+');
        
        curl_setopt($ch, CURLOPT_TIMEOUT, 120);
        curl_setopt($ch, CURLOPT_FILE, $fp);
        curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
        
        $success = curl_exec($ch);
        curl_close($ch);
        fclose($fp);
        
        if ($success) {
            $download_success = true;
        }
    }
    
    if (!$download_success) {
        header('Content-Type: application/json');
        echo json_encode(['success' => false, 'message' => '下载更新包失败']);
        exit;
    }
} catch (Exception $e) {
    header('Content-Type: application/json');
    echo json_encode(['success' => false, 'message' => '下载过程出错: ' . $e->getMessage()]);
    exit;
}

// 解压更新包
$extract_dir = "$temp_dir/extract";
if (!is_dir($extract_dir)) {
    if (!mkdir($extract_dir, 0755, true)) {
        header('Content-Type: application/json');
        echo json_encode(['success' => false, 'message' => '无法创建解压目录']);
        exit;
    }
}

// 清理解压目录
array_map('unlink', glob("$extract_dir/*.*"));
foreach (glob("$extract_dir/*", GLOB_ONLYDIR) as $dir) {
    deleteDir($dir);
}

// 解压文件
$zip = new ZipArchive;
$res = $zip->open($update_file);
if ($res === TRUE) {
    $zip->extractTo($extract_dir);
    $zip->close();
} else {
    header('Content-Type: application/json');
    echo json_encode(['success' => false, 'message' => '解压更新包失败']);
    exit;
}

// 自动导入 update.sql
$update_sql_file = $extract_dir . '/update.sql';
if (file_exists($update_sql_file)) {
    $sql_content = file_get_contents($update_sql_file);
    if ($sql_content !== false && trim($sql_content) !== '') {
        try {
            $pdo->exec("SET FOREIGN_KEY_CHECKS=0;");
            $statements = array_filter(array_map('trim', explode(';', $sql_content)));
            foreach ($statements as $statement) {
                if ($statement !== '') {
                    $pdo->exec($statement);
                }
            }
            $pdo->exec("SET FOREIGN_KEY_CHECKS=1;");
        } catch (Exception $e) {
            // 记录错误或返回失败
        }
    }
}

// 如果选择备份，则进行备份
if ($do_backup) {
    // 创建备份目录
    $backup_dir = '../backup/' . date('YmdHis');
    if (!is_dir($backup_dir)) {
        if (!mkdir($backup_dir, 0755, true)) {
            header('Content-Type: application/json');
            echo json_encode(['success' => false, 'message' => '无法创建备份目录']);
            exit;
        }
    }
    // 获取更新包中包含的文件列表
    $update_files = [];
    getFilesInDir($extract_dir, $update_files, $extract_dir);
    // 备份将被更新的文件
    foreach ($update_files as $file) {
        $relative_path = str_replace($extract_dir . '/', '', $file);
        $original_file = '../' . $relative_path;
        $backup_file = $backup_dir . '/' . $relative_path;
        if (file_exists($original_file)) {
            // 确保备份目录存在
            $backup_file_dir = dirname($backup_file);
            if (!is_dir($backup_file_dir)) {
                mkdir($backup_file_dir, 0755, true);
            }
            // 复制文件到备份目录
            copy($original_file, $backup_file);
        }
    }
    // 备份数据库
    $backup_sql_file = $backup_dir . '/database.sql';
    $db_host = defined('DB_HOST') ? DB_HOST : 'localhost';
    $db_user = defined('DB_USER') ? DB_USER : 'root';
    $db_pass = defined('DB_PASS') ? DB_PASS : '';
    $db_name = defined('DB_NAME') ? DB_NAME : '';
    $db_port = 3306;
    $mysqldump_path = 'mysqldump';
    $cmd = "$mysqldump_path -h{$db_host} -P{$db_port} -u{$db_user} -p\"{$db_pass}\" --default-character-set=utf8mb4 {$db_name} > \"{$backup_sql_file}\"";
    @exec($cmd);
    // 检查是否备份成功，否则用PHP导出
    if (!file_exists($backup_sql_file) || filesize($backup_sql_file) < 100) {
        $tables = $pdo->query("SHOW TABLES")->fetchAll(PDO::FETCH_COLUMN);
        $sql = "-- PHP导出备份\n";
        foreach ($tables as $table) {
            $create = $pdo->query("SHOW CREATE TABLE `$table`")->fetch(PDO::FETCH_ASSOC);
            $sql .= "\nDROP TABLE IF EXISTS `$table`;\n" . $create['Create Table'] . ";\n";
            $rows = $pdo->query("SELECT * FROM `$table`")->fetchAll(PDO::FETCH_ASSOC);
            if ($rows) {
                foreach ($rows as $row) {
                    $vals = array_map(function($v) use ($pdo) {
                        return isset($v) ? $pdo->quote($v) : 'NULL';
                    }, $row);
                    $sql .= "INSERT INTO `$table` (`" . implode('`,`', array_keys($row)) . "`) VALUES (" . implode(',', $vals) . ");\n";
                }
            }
        }
        file_put_contents($backup_sql_file, $sql);
    }
}

// 复制文件到根目录
function copyDir($src, $dst) {
    $dir = opendir($src);
    if (!is_dir($dst)) {
        mkdir($dst, 0755, true);
    }
    
    while (($file = readdir($dir)) !== false) {
        if ($file == '.' || $file == '..') {
            continue;
        }
        
        $srcFile = "$src/$file";
        $dstFile = "$dst/$file";
        
        if (is_dir($srcFile)) {
            copyDir($srcFile, $dstFile);
        } else {
            copy($srcFile, $dstFile);
        }
    }
    
    closedir($dir);
}

// 递归删除目录
function deleteDir($dir) {
    if (!is_dir($dir)) {
        return;
    }
    
    $files = array_diff(scandir($dir), ['.', '..']);
    foreach ($files as $file) {
        $path = "$dir/$file";
        is_dir($path) ? deleteDir($path) : unlink($path);
    }
    
    return rmdir($dir);
}

// 获取目录中的所有文件（递归）
function getFilesInDir($dir, &$results, $base_dir) {
    $files = scandir($dir);
    
    foreach ($files as $file) {
        if ($file === '.' || $file === '..') {
            continue;
        }
        
        $path = $dir . '/' . $file;
        
        if (is_dir($path)) {
            getFilesInDir($path, $results, $base_dir);
        } else {
            $results[] = $path;
        }
    }
}

// 复制更新文件到网站根目录
try {
    copyDir($extract_dir, '..');
} catch (Exception $e) {
    header('Content-Type: application/json');
    echo json_encode(['success' => false, 'message' => '复制更新文件失败: ' . $e->getMessage()]);
    exit;
}

// 清理临时文件
@unlink($update_file);
deleteDir($extract_dir);

// 记录更新日志
try {
    $stmt = $pdo->prepare("INSERT INTO update_logs (version, update_time, updated_by, backup) VALUES (?, NOW(), ?, ?)");
    $stmt->execute([$version, $admin['username'], $do_backup ? 1 : 0]);
} catch (Exception $e) {
    // 忽略日志记录错误
}

// 返回成功响应
header('Content-Type: application/json');
echo json_encode(['success' => true, 'message' => '更新成功' . ($do_backup ? '，已备份原文件' : '')]);
exit; 